from manimlib.imports import *


class SquareToCircle(Scene):
    def construct(self):
        for DIR in [LEFT, RIGHT+LEFT, UP, DOWN+UP]:
            circle = Circle()
            square = Square()
            square.flip(DIR)
            square.rotate(-3 * TAU / 8)
            circle.set_fill(PINK, opacity=0.5)
            self.play(ShowCreation(square))
            self.play(Transform(square, circle))
            self.play(FadeOut(square))



class DotMap(Scene):
    def construct(self):
        dots = dict()
        annos = dict()
        var_index = 0
        for x in range(-7, 8):
            for y in range(-4, 5):
                annos[f"{x}{y}"] = TexMobject(f"({x}, {y})")
                dots[f"{var_index}"] = Dot(np.array([x, y, 0]))
                var_index = var_index + 1
        for anno, dot in zip(annos.values(), dots.values()):
            self.add(anno)
            self.add(dot)
            self.wait(0.2)
            self.remove(anno)


class CoorPolygon(Scene):
    def construct(self):
        for x in range(-7, 8):
            for y in range(-4, 5):
                self.add(Dot(np.array([x, y, 0]), color=DARK_GREY))
        polygon = Polygon(
            np.array([3, 2, 0]),
            np.array([1, -1, 0]),
            np.array([-5, -4, 0]),
            np.array([-4, 4, 0]))
        self.play(ShowCreation(polygon),run_time=4)
        self.wait()


class CoorAlias(Scene):
    def construct(self):
        for x in range(-7, 8):
            for y in range(-4, 5):
                self.add(Dot(np.array([x, y, 0]), color=DARK_GREY))

        aliases = {
            "UP": UP,
            "np.array([0,1,0])": np.array([0, 1, 0]),
            "DOWN": DOWN,
            "np.array([0,-1,0])": np.array([0, -1, 0]),
            "LEFT": LEFT,
            "np.array([-1,0,0])": np.array([-1, 0, 0]),
            "RIGHT": RIGHT,
            "np.array([1,0,0])": np.array([1, 0, 0]),
            "UL": UL,
            "np.array([-1,1,0])": np.array([-1, 1, 0]),
            "DL": DL,
            "np.array([-1,-1,0])": np.array([-1, -1, 0]),
            "UR": UR,
            "np.array([1,1,0])": np.array([1, 1, 0]),
            "DR": DR,
            "np.array([1,-1,0])": np.array([1, -1, 0])}
        circle = Circle(color=RED, radius=0.5)
        self.add(circle)
        self.wait(0.5)

        for text, aliase in aliases.items():
            anno = TexMobject(f"\\texttt{{{text}}}")
            self.play(Write(anno, run_time=0.2))
            self.play(ApplyMethod(circle.shift, aliase))
            self.wait(0.2)
            self.play(FadeOut(anno, run_time=0.2))

class CoorArithmetic(Scene):
    def construct(self):
        for x in range(-7, 8):
            for y in range(-4, 5):
                self.add(Dot(np.array([x, y, 0]), color=DARK_GREY))

        circle = Circle(color=RED, radius=0.5)
        self.add(circle)
        self.wait(0.5)

        aliases = {
            "LEFT * 3": LEFT * 3,
            "UP + RIGHT / 2": UP + RIGHT / 2,
            "DOWN + LEFT * 2": DOWN + LEFT * 2,
            "RIGHT * 3.75 * DOWN": RIGHT * 3.75 * DOWN,
            # certain arithmetic won't work as you expected
            # In [4]: RIGHT * 3.75 * DOWN
            # Out[4]: array([ 0., -0.,  0.])
            "RIGHT * 3.75 + DOWN": RIGHT * 3.75 + DOWN}

        for text, aliase in aliases.items():
            anno = TexMobject(f"\\texttt{{{text}}}")
            self.play(Write(anno, run_time=0.2))
            self.play(ApplyMethod(circle.shift, aliase))
            self.wait(0.2)
            self.play(FadeOut(anno, run_time=0.2))


class AnimationFadeInFrom(Scene):
    def construct(self):
        square = Square()
        for label, edge in zip(
                ["LEFT", "RIGHT", "UP", "DOWN"], [LEFT, RIGHT, UP, DOWN]
        ):
            anno = TextMobject(f"Fade In from {label}")
            anno.shift(2 * DOWN)
            self.add(anno)

            self.play(FadeInFrom(square, edge))
            self.remove(anno, square)


class AnimationFadeInFromLarge(Scene):
    def construct(self):
        square = Square()

        for factor in [0.1, 0.5, 0.8, 1, 2, 5]:
            anno = TextMobject(f"Fade In from large scale\_factor={factor}")
            anno.shift(2 * DOWN)
            self.add(anno)

            self.play(FadeInFromLarge(square, scale_factor=factor))
            self.remove(anno, square)


class AnimationFadeInFromPoint(Scene):
    def construct(self):
        square = Square()
        for i in range(-6, 7, 2):
            anno = TextMobject(f"Fade In from point {i}")
            anno.shift(2 * DOWN)
            self.add(anno)
            self.play(FadeInFromPoint(square, point=i))
            self.remove(anno, square)


class AnimationGrowFromEdge(Scene):
    def construct(self):
        for label, edge in zip(
                ["LEFT", "RIGHT", "UP", "DOWN"], [LEFT, RIGHT, UP, DOWN]
        ):
            anno = TextMobject(f"Grow from {label} edge")
            anno.shift(2 * DOWN)
            self.add(anno)
            square = Square()
            self.play(GrowFromEdge(square, edge))
            self.remove(anno, square)


class AnimationFadeInFromDiagonal(Scene):
    def construct(self):
        square = Square()
        for diag in [UP + LEFT, UP + RIGHT, DOWN + LEFT, DOWN + RIGHT]:
            self.play(FadeInFrom(square, diag))